package main

import (
	"3-6/proto/user"         // 导入protobuf生成的客户端代码（包含UserClient接口和请求/响应结构体）
	"context"                // 上下文包，gRPC强制要求传递context，用于控制调用生命周期（超时、取消、元数据传递等）
	"google.golang.org/grpc" // gRPC核心库，提供客户端连接建立、方法调用等底层能力
	// 提供不安全的传输层凭证（不使用TLS加密），仅用于开发环境，生产环境需替换为TLS证书
	"google.golang.org/grpc/credentials/insecure"
	"log" // 日志包，用于输出程序运行状态和错误信息
)

func main() {
	// 1. 建立与gRPC服务端的TCP连接（基于HTTP/2协议）
	// 参数说明：
	// - 第一个参数：服务端地址，格式为"IP:端口"，此处连接本地1234端口（需与服务端监听端口一致）
	// - 第二个参数：连接选项（可变参数），grpc.WithTransportCredentials指定传输层安全策略
	// - insecure.NewCredentials()：创建不加密的凭证，开发环境简化配置使用；生产环境需用grpc.WithTransportCredentials(tls.Creds(...))配置TLS加密
	clientConn, err := grpc.Dial(
		"127.0.0.1:1234", // 服务端地址
		grpc.WithTransportCredentials(insecure.NewCredentials()), // 开发环境无加密配置
	)
	if err != nil {
		// 连接失败为致命错误（如服务端未启动、端口错误、网络不通等），直接终止程序
		log.Fatal("无法与gRPC服务端建立连接：", err)
	}
	// 延迟关闭连接：确保程序退出时释放TCP连接资源，避免连接泄漏（即使程序异常退出也会执行）
	defer func(clientConn *grpc.ClientConn) {
		err := clientConn.Close()
		if err != nil {
			log.Println("关闭连接失败：", err)
		}
	}(clientConn)

	// 2. 创建用户服务的客户端实例（类型安全的调用接口）
	// user.NewUserClient：由protoc编译器根据user.proto中的service User自动生成的函数
	// 作用：将底层连接与业务接口绑定，提供与服务端定义一致的方法（如GetUser）
	// 注意：客户端实例是线程安全的，可在多个goroutine中复用，无需为每个请求创建新实例
	userClient := user.NewUserClient(clientConn)

	// 3. 调用远程服务的GetUser方法（核心业务逻辑）
	// 参数说明：
	// - 第一个参数：context.Context，控制本次调用的超时时间、取消信号等
	//   context.Background()：创建一个空上下文，无超时和取消机制；实际开发中常用context.WithTimeout设置超时（如5秒）：
	//   ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	//   defer cancel() // 确保超时后释放资源
	// - 第二个参数：请求结构体指针，需与protobuf定义的GetUserReq一致（此处查询ID为"1"的用户）
	resp, err := userClient.GetUser(
		context.Background(),      // 上下文（实际项目建议设置超时）
		&user.GetUserReq{Id: "1"}, // 请求参数
	)
	if err != nil {
		// 调用失败：可能的错误类型包括
		// - 网络错误：连接断开、服务端未启动（transport is closing）
		// - 服务端返回的业务错误：如"用户不存在"（需服务端通过status.Errorf返回）
		// - 超时错误：context.DeadlineExceeded
		log.Fatal("调用GetUser方法失败：", err)
	}

	// 4. 处理服务端返回的成功响应
	// %+v：打印结构体的字段名和值，方便查看详细信息
	log.Printf("调用成功，用户信息：%+v", resp)
}
